<template>
  <div class="suggestion">
    <div class="wrapper flex-column">
      <div class="search-add flex">
        <a-input
          v-model:value="keyword"
          placeholder="搜索标题/内容"
          @input="inputSearch"
        >
          <template #prefix>
            <SearchOutlined style="cursor: pointer" @click="getList" />
          </template>
        </a-input>
        <a-dropdown key="create">
          <a-button type="primary" class="ml-15"><FormOutlined />创建</a-button>
          <template #overlay>
            <a-menu>
              <a-menu-item>
                <div @click="createNewItem(1)">新功能/优化建议</div>
              </a-menu-item>
              <a-menu-item>
                <div @click="createNewItem(2)">bug复现</div>
              </a-menu-item>
            </a-menu>
          </template>
        </a-dropdown>
      </div>

      <div class="content-wrap flex-column mt-15">
        <div class="filter-wrap flex">
          <div class="total-num flex">
            <div class="total">总数：{{ totalNum }}</div>
            <div class="my ml-10">由我创建的：{{ myNum }}</div>
          </div>
          <div class="dropdown-list">
            <RedoOutlined
              @click="refreshAll"
              title="重置全部过滤项"
              style="cursor: pointer"
            />
            <a-dropdown key="user">
              <span>{{ userConfig.text }}<CaretDownOutlined /></span>
              <template #overlay>
                <a-menu v-model:selectedKeys="userConfig.user">
                  <a-menu-item
                    v-for="item of userConfig.list"
                    :key="item.value"
                    @click="changeUser(item)"
                    >{{ item.label }}</a-menu-item
                  >
                </a-menu>
              </template>
            </a-dropdown>

            <a-dropdown key="contentType">
              <span>{{ contentType.text }}<CaretDownOutlined /></span>
              <template #overlay>
                <a-menu v-model:selectedKeys="contentType.typeValue">
                  <a-menu-item
                    v-for="item of contentType.list"
                    :key="item.value"
                    @click="changeType(item)"
                    >{{ item.label }}</a-menu-item
                  >
                </a-menu>
              </template>
            </a-dropdown>

            <a-dropdown key="contentStatus">
              <span>{{ contentStatus.text }}<CaretDownOutlined /></span>
              <template #overlay>
                <a-menu v-model:selectedKeys="contentStatus.statusValue">
                  <a-menu-item
                    v-for="item of contentStatus.list"
                    :key="item.value"
                    @click="changeStatus(item)"
                    >{{ item.label }}</a-menu-item
                  >
                </a-menu>
              </template>
            </a-dropdown>

            <a-dropdown key="sortMethod">
              <span>{{ sortMethod.text }}<CaretDownOutlined /></span>
              <template #overlay>
                <a-menu v-model:selectedKeys="sortMethod.sort">
                  <a-menu-item
                    v-for="item of sortMethod.list"
                    :key="item.value"
                    @click="changeSort(item)"
                    >{{ item.label }}</a-menu-item
                  >
                </a-menu>
              </template>
            </a-dropdown>
            <SortAscendingOutlined
              v-if="sortType === 1"
              title="正序"
              class="ml-5"
              style="cursor: pointer"
              @click="changeSortType(2)"
            />
            <SortDescendingOutlined
              v-else
              title="倒序"
              class="ml-5"
              style="cursor: pointer"
              @click="changeSortType(1)"
            />
          </div>
        </div>

        <div class="suggestion-list">
          <div class="flex-center" style="height: 100%" v-if="loading">
            <a-spin size="large" tip="Loading..." />
          </div>
          <template v-else>
            <div
              v-for="(item, index) of list"
              :key="index"
              class="suggestion-item"
            >
              <div class="status">
                <div
                  class="status-corner"
                  :style="{
                    borderColor: `${
                      statusObj[item.status]?.color
                    } transparent transparent transparent`,
                  }"
                ></div>
                <span class="status-text">{{
                  statusObj[item.status]?.text
                }}</span>
              </div>
              <div class="title" @click="showDetail(item)">
                {{ item.title }}
              </div>
              <div class="content text-ellipsis mt-15">
                {{ item.noTagContent }}
              </div>
              <div class="info flex mt-15">
                <div class="user-time flex">
                  <div class="user flex-column-center">
                    <i class="iconfont icon-user"></i>
                    <span>{{ item.user_name }}</span>
                  </div>
                  <div class="time ml-15 flex-column-center">
                    <i class="iconfont icon-time"></i>
                    <span>{{ item.create_time }}</span>
                  </div>
                </div>
                <div class="see-comment flex">
                  <div class="see flex-column-center">
                    <i class="iconfont icon-see"> </i>
                    <span> {{ item.see }}</span>
                  </div>
                  <div class="comment flex-column-center ml-15">
                    <i class="iconfont icon-comment"></i>
                    <span>{{ item.comment_num }}</span>
                  </div>
                </div>
              </div>
            </div>
          </template>
        </div>
      </div>
    </div>
    <a-modal
      width="800px"
      v-model:open="dialogConfig.show"
      :title="dialogConfig.title"
      :confirm-loading="dialogConfig.loading"
      @ok="handleOk"
      @cancel="handleCancel"
    >
      <div class="title flex-column mt-15">
        <div class="label">
          <span class="label-required mr-5">*</span>
          <span>标题</span>
        </div>
        <div class="input-wrap">
          <a-input
            v-model:value="form.title"
            :placeholder="formConfig.titlePlaceholder"
            :style="{
              borderColor: formConfig.showTitleError ? '#f56c6c' : '',
            }"
            @input="inputChange"
          />
        </div>
        <div class="danger-text" v-if="formConfig.showTitleError">
          请输入标题
        </div>
      </div>

      <div class="title flex-column mt-20">
        <div class="label">
          <span class="label-required mr-5">*</span>
          <span>内容描述</span>
          <span class="tips ml-5">(如有必要可在富文本编辑器中插入图片~)</span>
        </div>
        <div
          class="rich-text-wrap mb-20"
          :style="{
            borderColor: formConfig.showDescError ? '#f56c6c' : '',
          }"
        >
          <Toolbar
            :mode="mode"
            :defaultConfig="toolbarConfig"
            :editor="editorRef"
            style="border-bottom: 1px solid #ccc"
          />
          <Editor
            style="height: 300px; overflow-y: hidden"
            v-model="valueHtml"
            :defaultConfig="editorConfig"
            :mode="mode"
            @onCreated="handleCreated"
            @onChange="handleChange"
          />
        </div>
        <div
          class="danger-text"
          v-if="formConfig.showDescError"
          style="bottom: 0"
        >
          请详细描述你的问题
        </div>
      </div>
    </a-modal>
  </div>
</template>

<script setup>
import { onBeforeUnmount, onMounted, reactive, ref, shallowRef } from "vue";
import { useRouter } from "vue-router";
import {
  FormOutlined,
  SearchOutlined,
  CaretDownOutlined,
  SortAscendingOutlined,
  SortDescendingOutlined,
  RedoOutlined,
} from "@ant-design/icons-vue";
import { message } from "ant-design-vue";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import "@wangeditor/editor/dist/css/style.css"; // 引入 css

import {
  getSuggestion,
  addSuggestion,
  getSuggestionDetail,
} from "../../api/suggestion";
import { getLocal } from "../../utils/storage";
import { debounce } from "../../utils/util";

const router = useRouter();

const keyword = ref(null);
const inputSearch = debounce(getList, 500, false);
const totalNum = ref(0);
const myNum = ref(0);
function refreshAll() {
  userConfig.value.user = [0];
  userConfig.value.text = "创建者";
  contentType.value.typeValue = [0];
  contentType.value.text = "内容类型";
  contentStatus.value.statusValue = ["all"];
  contentStatus.value.text = "内容状态";
  sortMethod.value.sort = ["default"];
  sortMethod.value.text = "排序方式";
  getList();
}
const userConfig = ref({
  user: [0],
  text: "创建者",
  list: [
    {
      label: "全部",
      value: 0,
    },
    {
      label: "只看我的",
      value: 1,
    },
    {
      label: "不看我的",
      value: 2,
    },
  ],
});
const changeUser = (item) => {
  userConfig.value.text = item.value ? item.label : "创建者";
  userConfig.value.user = [item.value];
  getList();
};
const contentType = ref({
  typeValue: [0],
  text: "内容类型",
  list: [
    {
      label: "全部",
      value: 0,
    },
    {
      label: "新功能/优化建议",
      value: 1,
    },
    {
      label: "bug",
      value: 2,
    },
  ],
});
const changeType = (item) => {
  contentType.value.text = item.value ? item.label : "内容类型";
  contentType.value.typeValue = [item.value];
  getList();
};
const contentStatus = ref({
  statusValue: ["all"],
  text: "内容状态",
  list: [
    {
      label: "全部",
      value: "all",
    },
    {
      label: "未查收",
      value: 0,
    },
    {
      label: "处理中",
      value: 1,
    },
    {
      label: "已解决",
      value: 2,
    },
    {
      label: "已拒绝",
      value: 3,
    },
  ],
});
const changeStatus = (item) => {
  contentStatus.value.text = item.value !== "all" ? item.label : "内容状态";
  contentStatus.value.statusValue = [item.value];
  getList();
};
const sortMethod = ref({
  sort: ["default"],
  text: "排序方式",
  list: [
    {
      label: "默认",
      value: "default",
    },
    {
      label: "创建时间",
      value: "create_time",
    },
    {
      label: "浏览量",
      value: "see",
    },
    {
      label: "评论数",
      value: "comment_num",
    },
  ],
});
const changeSort = (item) => {
  sortMethod.value.text = item.value === "default" ? "排序方式" : item.label;
  sortMethod.value.sort = [item.value];
  getList();
};
const sortType = ref(1);
const changeSortType = (type) => {
  sortType.value = type;
  getList();
};

const statusObj = {
  0: {
    color: "#929292",
    text: "未查收",
  },
  1: {
    color: "#2196f3",
    text: "处理中",
  },
  2: {
    color: "#4caf50",
    text: "已解决",
  },
  3: {
    color: "#f44336",
    text: "已拒绝",
  },
};
function showDetail(item) {
  getSuggestionDetail({
    id: item.id,
  }).then((res) => {
    if (res.code === 0) {
      router.push({
        path: "/common/suggestion/detail",
        query: {
          id: item.id,
        },
      });
    }
  });
}

const pages = ref({
  page: 1,
  limit: 10,
  total: 0,
});
const loading = ref(false);
function getList() {
  let params = {
    ...pages.value,
    keyword: keyword.value,
    type:
      contentType.value.typeValue[0] === 0
        ? ""
        : contentType.value.typeValue[0],
    status:
      contentStatus.value.statusValue[0] === "all"
        ? ""
        : contentStatus.value.statusValue[0],
    selfFlag: userConfig.value.user[0] === 0 ? "" : userConfig.value.user[0],
    sortProp:
      sortMethod.value.sort[0] === "default" ? "" : sortMethod.value.sort[0],
    sortType: sortType.value,
  };
  loading.value = true;
  getSuggestion(params).then((res) => {
    loading.value = false;
    if (res.code === 0) {
      list.value = res.data;
      res.data.forEach((item) => {
        item.noTagContent = item.content.replace(/<[^>]*>/g, "");
      });
      totalNum.value = res.total;
      myNum.value = res.myTotal;
    }
  });
}

onMounted(() => {
  getList();
});
const list = ref([]);
// 富文本编辑器
const mode = "default";
const editorRef = shallowRef();
const valueHtml = ref(null);
const toolbarConfig = {
  excludeKeys: [
    "insertLink",
    "viewImageLink",
    "insertVideo",
    "emotion",
    // "fullScreen",
    "codeBlock",
    "todo",
  ], //排除不需要的菜单
};
const editorConfig = {
  placeholder: "请以简洁、完整的文字描述你的需求...",
  MENU_CONF: {
    insertImage: {
      onInsertedImage: (imageNode) => {
        const { src, alt, url, href } = imageNode;
        console.log("inserted image", src, alt, url, href);
      },
      checkImage: handleCheckImage,
    },
    uploadImage: {
      server: "/api/suggestion/upload",
      headers: {
        Authorization: getLocal("plan_user_id"),
      },
      customInsert(res, insertFn) {
        insertFn(res.data.url);
      },
    },
  },
};
function handleCreated(editor) {
  console.log(editor);
  editorRef.value = editor; // 记录editor实例
}
function handleChange(value) {
  console.log(value);
  formConfig.showDescError = false;
}
function handleCheckImage(src, alt, url) {
  console.log(alt, src, url);
  return true;
}
onBeforeUnmount(() => {
  const editor = editorRef.value;
  if (editor === null) return;
  editor?.destroy?.();
});

const currentType = ref(null);
function createNewItem(type) {
  currentType.value = type;
  if (type === 1) {
    dialogConfig.value.title = "添加【新功能/优化建议】";
    formConfig.titlePlaceholder = "请为你的建议创建一个合理的标题";
  } else {
    dialogConfig.value.title = "bug复现";
    formConfig.titlePlaceholder = "请为你的bug创建一个合理的标题";
  }
  form.value.title = "";
  valueHtml.value = "<p><br></p>";
  formConfig.showTitleError = false;
  formConfig.showDescError = false;
  dialogConfig.value.show = true;
}
const dialogConfig = ref({
  show: false,
  title: "",
  loading: false,
});
const formConfig = reactive({
  titlePlaceholder: "",
  showTitleError: false,
  showDescError: false,
});
const form = ref({
  title: "",
});
const inputChange = (e) => {
  formConfig.showTitleError = false;
};
function handleOk() {
  if (!form.value.title) {
    formConfig.showTitleError = true;
    return;
  }
  if (valueHtml.value === "<p><br></p>") {
    formConfig.showDescError = true;
    return;
  }
  dialogConfig.value.loading = true;
  let params = {
    title: form.value.title,
    content: valueHtml.value,
    type: currentType.value,
    username: getLocal("plan_user_name"),
  };
  addSuggestion(params).then((res) => {
    dialogConfig.value.loading = false;
    if (res.code === 0) {
      message.success("已收到您的反馈，加急处理中~");
      getList();
      dialogConfig.value.show = false;
    }
  });
}
function handleCancel() {}
</script>

<style scoped lang="less">
.suggestion {
  height: 100%;
  padding: 16px;
  font-size: 16px;
  background-image: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);

  .wrapper {
    width: 1200px;
    min-width: 1200px;
    margin: 0 auto;
    border-radius: 8px 8px 0 0;
    height: 100%;

    .content-wrap {
      flex: 1;
      overflow: hidden;

      .filter-wrap {
        border: 1px solid @border-color;
        padding: 32px 16px;
        background-color: #f6f8fa;
        // background-image: linear-gradient(120deg, #fdfbfb 0%, #ebedee 100%);
        justify-content: space-between;
        color: #555;
        font-size: 14px;
        border-radius: 8px 8px 0 0;

        .total-num {
          font-size: 16px;
          align-items: baseline;

          .total {
            color: #000;
            font-weight: bold;
          }

          .my {
            font-size: 14px;
          }
        }

        .dropdown-list {
          .ant-dropdown-trigger {
            margin-left: 32px;

            &:hover {
              opacity: 0.7;
              cursor: pointer;
            }

            .anticon-caret-down {
              color: @shallow-text-color;
              font-size: 12px;
              margin-left: 3px;
            }
          }
        }
      }

      .suggestion-list {
        flex: 1;
        overflow-y: auto;
        border: 1px solid #dde0e2;
        background-color: #fff;

        // 滚动条样式
        &::-webkit-scrollbar {
          width: 5px;
        }

        // 滚动条的轨道的两端按钮，允许通过点击微调小方块的位置。
        &::-webkit-scrollbar-button {
          display: none;
        }
        // 滚动条的轨道（里面装有Thumb）
        &::-webkit-scrollbar-track {
          background: transparent;
        }
        // 滚动条的轨道（里面装有Thumb）
        &::-webkit-scrollbar-track-piece {
          background-color: transparent;
        }
        // 滚动条里面的小方块，能向上向下移动（或往左往右移动，取决于是垂直滚动条还是水平滚动条）
        &::-webkit-scrollbar-thumb {
          background: @main-color !important;
          cursor: pointer;
          border-radius: 4px;
        }
        // 边角，即两个滚动条的交汇处
        &::-webkit-scrollbar-corner {
          display: none;
        }
        // 两个滚动条的交汇处上用于通过拖动调整元素大小的小控件
        &::-webkit-resizer {
          display: none;
        }

        .suggestion-item {
          letter-spacing: 1px;
          background-color: #fff;
          padding: 16px;
          padding-left: 66px;
          border-bottom: 1px solid #dde0e2;
          position: relative;

          .status {
            width: 200px;
            position: absolute;

            &-corner {
              position: absolute;
              top: -16px;
              left: -66px;
              width: 0;
              height: 0;
              border-style: solid;
              border-width: 50px 50px 0 0;
              z-index: 1;
              border-color: #929292 transparent transparent transparent;
            }

            &-text {
              position: absolute;
              top: -7px;
              left: -66px;
              transform: rotate(-45deg);
              color: #fff;
              font-size: 11px;
              z-index: 2;
            }
          }

          .title {
            font-weight: bold;
            font-size: 18px;
            width: max-content;

            &:hover {
              cursor: pointer;
              color: @click-color;
            }
          }

          .content {
            font-size: 14px;
            max-width: 50%;
            color: @shallow-text-color;
          }

          .info {
            font-size: 14px;
            color: #a7a5a5;
            justify-content: space-between;

            .iconfont {
              margin-right: 3px;
            }
          }

          &:hover {
            background-color: #f6f8fa;
          }
        }
      }
    }
  }
}
</style>

<style lang="less">
.ant-modal-content {
  .ant-modal-title {
    text-align: center;
  }

  .title {
    position: relative;

    .label {
      &-required {
        color: @danger-color;
      }

      .tips {
        color: @shallow-text-color;
        font-size: 12px;
      }
    }

    .rich-text-wrap {
      border: 1px solid #ccc;
    }

    .danger-text {
      position: absolute;
      bottom: -20px;
      font-size: 12px;
      color: @danger-color;
    }
  }
}
</style>
